#include "extraaudio.h"

ExtraAudio::ExtraAudio() {}
/**
 * @brief ExtraAudio::extraAduio 从视频中提取音频
 * @param src   输入路径
 * @param dst   输出路径
 * @return
 */
int ExtraAudio::extraAduio(const char * src,const char* dst)
{
    // 1.处理参数
    av_log_set_level(AV_LOG_DEBUG);
    int ret = -1;
    int index = -1;

    AVFormatContext* pFmtCtx = NULL;
    AVFormatContext* oFmtCtx = NULL;
    const AVOutputFormat* outFmt = NULL;
    AVStream* outStream = NULL;
    AVStream* inStream = NULL;
    AVPacket pkt;


    // 2.打开多媒体文件
    ret = avformat_open_input(&pFmtCtx,src,NULL,NULL);

    if(ret < 0)
    {
        //av_log(NULL,AV_LOG_ERROR,"%s\n",av_err2str(ret));
        return -1;
    }

    // 3.从多媒体文件中找到音频流
    index = av_find_best_stream(pFmtCtx,AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);
    if(index < 0)
    {
        //av_log(pFmtCtx,AV_LOG_ERROR,"does not include audio stream\n");
        goto _ERROR;
    }

    // 4.打开目的文件的上下文
    oFmtCtx = avformat_alloc_context();
    if(!oFmtCtx)
    {
        //(NULL,AV_LOG_ERROR,"no memory\n");
        goto _ERROR;
    }

    outFmt = av_guess_format(NULL,dst,NULL);
    oFmtCtx->oformat = outFmt;

    // 5.为目的文件，创建一个新的音频流
    outStream = avformat_new_stream(oFmtCtx,NULL);

    // 6.设置输出音频参数
    inStream = pFmtCtx->streams[index];
    avcodec_parameters_copy(outStream->codecpar,inStream->codecpar);
    outStream->codecpar->codec_tag = 0;

    // 绑定
    ret = avio_open2(&oFmtCtx->pb,dst,AVIO_FLAG_WRITE,NULL,NULL);
    if(ret < 0)
    {
        //av_log(oFmtCtx,AV_LOG_ERROR,"%s\n",av_err2str(ret));
        goto _ERROR;
    }
    // 7.写多媒体文件头到目标文件中
    ret = avformat_write_header(oFmtCtx,NULL);

    if(ret < 0 )
    {
        //av_log(oFmtCtx,AV_LOG_ERROR,"%s\n",av_err2str(ret));
        goto _ERROR;
    }

    // 8.从源多媒体文件中读到音频数据目的文件中
    while(av_read_frame(pFmtCtx,&pkt) >= 0)
    {
        if(pkt.stream_index == index)
        {
            pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base,
                                       (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
            pkt.dts = pkt.pts;
            pkt.duration = av_rescale_q(pkt.duration,inStream->time_base,outStream->time_base);
            pkt.stream_index = 0;
            pkt.pos = -1;
            av_interleaved_write_frame(oFmtCtx,&pkt);
            av_packet_unref(&pkt);
        }
    }

    // 9.写多媒体文件尾到文件中
    av_write_trailer(oFmtCtx);

    // 10.资源释放
_ERROR:
    if(pFmtCtx)
    {
        avformat_close_input(&pFmtCtx);
        pFmtCtx = NULL;
    }
    if(oFmtCtx && oFmtCtx->pb)
    {
        avio_close(oFmtCtx->pb);
    }
    if(oFmtCtx)
    {
        avformat_free_context(oFmtCtx);
        oFmtCtx = NULL;
    }

    return 0;
}
